#ifndef _UTIL_TOOLS_H__
#define _UTIL_TOOLS_H__

/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author zhouyan
 * @brief 相关转换函数
*/
#include "sys_inc.h"
#include "tools/m_sleep.h"

static inline uint8_t BCDtoASCII(uint8_t bcd)
{
    return (bcd&0x0F)+((bcd>>4)*10);
}

static inline uint8_t ASCIItoBCD(uint8_t data)
{
    return static_cast<uint8_t>(((data/10)<<4) + (data%10));
}

static inline int ASCIItoBCD_U32(uint32_t data, uint8_t* bcd)
{
    int idx = 0;
    int offset = 0;
    uint32_t b = 10;
    bcd[idx] = 0;

    do
    {
        bcd[idx] |= data % 10 << offset;
        data = data / 10;

        b = b * 10;
        if (offset == 0)
        {
            offset = 4;
        }
        else
        {
            offset = 0; bcd[++idx] = 0;
        }
    } while (data);
    if (offset == 4)
        ++idx;
    return idx;
}


#define GET_HIGH_BYTE(data) (((data) >> 8) & 0xFF)
#define GET_LOW_BYTE(data) ((data) & 0xFF)

#define GET_INT64_FROM_INT16(tab_int16, index) \
    (((int64_t)tab_int16[(index)    ] << 48) + \
     ((int64_t)tab_int16[(index) + 1] << 32) + \
     ((int64_t)tab_int16[(index) + 2] << 16) + \
      (int64_t)tab_int16[(index) + 3])

#define GET_INT32_FROM_INT16(tab_int16, index) ((tab_int16[(index)] << 16) + tab_int16[(index) + 1])
#define GET_INT32_FROM_INT8(tab_int8, index) \
    ((tab_int8[(index)    ] << 24) + \
     (tab_int8[(index) + 1] << 16) + \
     (tab_int8[(index) + 2] << 8) + \
      tab_int8[(index) + 3])

#define GET_INT16_FROM_INT8(tab_int8, index) ((tab_int8[(index)] << 8) + tab_int8[(index) + 1])

#define SET_INT16_TO_INT8(tab_int8, index, value) \
    do { \
        tab_int8[(index)] = (value) >> 8;  \
        tab_int8[(index) + 1] = (value) & 0xFF; \
    } while (0)
#define SET_INT32_TO_INT16(tab_int16, index, value) \
    do { \
        tab_int16[(index)    ] = (value) >> 16; \
        tab_int16[(index) + 1] = (value); \
    } while (0)
#define SET_INT64_TO_INT16(tab_int16, index, value) \
    do { \
        tab_int16[(index)    ] = (value) >> 48; \
        tab_int16[(index) + 1] = (value) >> 32; \
        tab_int16[(index) + 2] = (value) >> 16; \
        tab_int16[(index) + 3] = (value); \
    } while (0)

float modbus_get_float(const uint16_t *src);
float modbus_get_float_abcd(const uint16_t *src);
float modbus_get_float_dcba(const uint16_t *src);
float modbus_get_float_badc(const uint16_t *src);
float modbus_get_float_cdab(const uint16_t *src);

void modbus_set_float(float f, uint16_t *dest);
void modbus_set_float_abcd(float f, uint16_t *dest);
void modbus_set_float_dcba(float f, uint16_t *dest);
void modbus_set_float_badc(float f, uint16_t *dest);
void modbus_set_float_cdab(float f, uint16_t *dest);


std::string GetSysTimeString( void );
std::string TimeToString(time_t rawtime);

// 获取时间字符串，tm为空时获取当前时间字符串
std::string GetTimeString( struct tm * tm=nullptr );

// 获取时间戳，strTm为空时获取当前时间戳
time_t GetTimeStamp(std::string strTm="");

std::string FloatToString(float k, float v);
std::string FloatToString(float v);
std::string FloatToString(double v);
std::string i32toa(int i);
std::string u32toa(uint32_t i);
std::string i64toa(int64_t i);
std::string u64toa(uint64_t i);
std::string dtoa(double v);
static inline std::string ftoa(float v) {return dtoa(static_cast<double>(v));}

template<typename _I, typename _Tp>
bool stl_containof(const _I& container, const _Tp& v) {
    return std::find(container.begin(), container.end(), v) != container.end();
}

#endif
